/**
 * Copyright 2011 HNB. All rights reserved.
 * HNB PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package my.hnb.android.view.common;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;

import my.hnb.android.common.ActionEvent;
import my.hnb.android.common.AppInfo;
import my.hnb.android.common.ModelEvent;
import my.hnb.android.constant.Constants;
import my.hnb.android.constant.EventConstant;
import my.hnb.android.constant.IntentConstants;
import my.hnb.android.constant.SharedPref;
import my.hnb.android.controller.UserController;
import my.hnb.android.dto.OptionItemDTO;
import my.hnb.android.dto.SongDTO;
import my.hnb.android.dto.SongTable;
import my.hnb.android.model.SQLUtils;
import my.hnb.android.ultils.AppUltils;
import my.hnb.android.ultils.DateUtil;
import my.hnb.android.ultils.Encryption;
import my.hnb.android.ultils.MyLog;
import my.hnb.android.ultils.StringUtil;
import my.hnb.android.ultils.download.DownloadFile;
import my.hnb.android.ultils.download.ExternalStorage;
import my.hnb.android.view.base.BaseActivity;
import my.hnb.songnhac.R;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.util.Log;
import android.view.View;

/**
 * Splashscreen application
 * @author BANGHN
 */
public class Splashscreen extends BaseActivity {
	public static final String PREFS_PRIVATE = "my.hnb.songnhac";
	final int ACTION_UPDATE_OK = 1;
	final int ACTION_UPDATE_LATER = 0;
	
	//danh sach bai hat load truoc
	ArrayList<SongDTO> modelData = new ArrayList<SongDTO>();
	boolean isFinishCheckUpdate = false;
	boolean isFinishRequestSong = false;
	private boolean isTimeOut = false; 
	private CountDownTimer countDownTimer;
	CountDownTimer timerCheckUpdate = null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		isTimeOut = false;
		setContentView(R.layout.layout_splash_screen);
		this.setTitleText(StringUtil.getString(R.string.app_title));
		ivMenu.setVisibility(View.GONE);
		initData();
		//Log.d("Splashscreen", "Splashscreen" + new Encryption().encrypt(AppInfo.K_LINK, "/u/215767793/KaraokeSongs/SongUpdateTest.txt"));
	}

	private void initData() {
		if (!AppUltils.checkExistsDataBase()) {
			isFinishCheckUpdate = true;
			new InitDatabase().execute("");
		} else {
			new CountDownTimer(1500, 500) {
				public void onTick(long millisUntilFinished) {
				}

				public void onFinish() {
					requesetGetSongs();
					//gotoMainView();
				}
			}.start();
			
			if(AppUltils.checkNetworkAccess()){
				Log.d("Splashscreen", "checkNetworkAccess = true");
				timerCheckUpdate = newCountDownTimer();
				timerCheckUpdate.start();
				new CheckUpdateSong().execute(Constants.URL_SONG_UPDATE + new Encryption().decrypt(AppInfo.K_LINK, Constants.K_SONG));
				new DownloadAdTask().execute(Constants.URL_ADD + new Encryption().decrypt(AppInfo.K_LINK, Constants.K_ADD));
			}else{
				isFinishCheckUpdate = true;
			}
		}
	}

	
	
	@SuppressWarnings("unchecked")
	@Override
	public void handleModelViewEvent(ModelEvent modelEvent) {
		ActionEvent act = modelEvent.getActionEvent();
		switch (act.action) {
		case EventConstant.GET_SONGS: {
			modelData = (ArrayList<SongDTO>) modelEvent.getModelData();
			isFinishRequestSong = true;
			closeProgressDialog();
			if(isFinishCheckUpdate && AppInfo.getInstance().isHaveUpdate){
				showDialogConfirmUpdate();
			}else if(isFinishCheckUpdate){
				gotoMainView();	
			}
			break;
		}
		default:
			super.handleModelViewEvent(modelEvent);
			break;
		}
	}
	
	private void showDialogConfirmUpdate(){
		AppUltils.showDialogConfirm(this,
				StringUtil.getString(R.string.update_notice_title),
				StringUtil.getString(R.string.update_notice_content),
				StringUtil.getString(R.string.button_agree),
				ACTION_UPDATE_OK, 
				StringUtil.getString(R.string.button_later),
				ACTION_UPDATE_LATER, null);
	}
	
	
	@Override
	public void handleErrorModelViewEvent(ModelEvent modelEvent) {
		ActionEvent act = modelEvent.getActionEvent();
		switch (act.action) {
		case EventConstant.GET_SONGS: {
			closeProgressDialog();
			gotoMainView();
			break;
		}
		default:
			super.handleModelViewEvent(modelEvent);
			break;
		}
	}
	
	@Override
	public void onEvent(View v, int action, Object userData) {
		switch (action) {
		case ACTION_UPDATE_OK:
			new UpdateDataAsync().execute("");
			break;
		case ACTION_UPDATE_LATER:
			gotoMainView();
			break;
		default:
			super.onEvent(v, action, userData);
			break;
		}
	}
	
	
	/**
	 * Di toi man hinh chinh
	 * @author BANGHN
	 */
	private void gotoMainView() {
		Bundle b = new Bundle();
		b.putSerializable(IntentConstants.INTENT_DATA, modelData);
		ActionEvent e = new ActionEvent();
		e.sender = this;
		e.viewData = b;
		e.action = EventConstant.GOTO_KARAOKE_LIST;
		UserController.getInstance().handleSwitchActivity(e);
	}

	
	
	/**
	 * Request lay danh sach bai nhac
	 * @author BANGHN
	 */
	private void requesetGetSongs() {
		ActionEvent e = new ActionEvent();
		Bundle b = new Bundle();
		b.putInt(IntentConstants.INTENT_PAGE_NUMBER, 1);
		e.viewData = b;
		e.action = EventConstant.GET_SONGS;
		e.sender = this;
		UserController.getInstance().handleViewEvent(e);
		
	}
	
	
	/**
	 * Dang khoi tao du lieu
	 * 
	 * @author BANGHN
	 */
	private class InitDatabase extends AsyncTask<String, Void, Exception> {
		@Override
		protected void onPreExecute() {
			showProgressDialog("Khởi tạo dữ liệu lần đầu...");
		}

		@Override
		protected Exception doInBackground(String... params) {
			try {
				copyDatabaseAndUnzip();
			} catch (Exception e) {
				return e;
			}
			return null;
		}

		@Override
		protected void onPostExecute(Exception result) {
			if (result != null) {
				gotoMainView();
			} else {
				updateSynInfoAfterInit();
				//gotoMainView();
				requesetGetSongs();
			}
			MyLog.logToFile("DownloadDB", "Finished init DB ");
		}
	}

	/**
	 * Copy database va giai nen
	 * 
	 * @author BANGHN
	 */
	private void copyDatabaseAndUnzip() {
		AppUltils.deleteDatabase();
		File zipDir = ExternalStorage.getFileDBPath();
		File zipFile = new File(zipDir.getPath() + "/snKaraoke.zip");
		File outputDir = ExternalStorage.getFileDBPath();
		// File path to store .zip file before unzipping
		try {
			AppUltils.copyDataBaseFromAssets();
			AppUltils.unzipFile(getApplicationContext(), zipFile, outputDir);
		} finally {
			zipFile.delete();
		}

	}
	
	
	///////////////////////////////////////////////////////////////////////////
	//DOWNLOAD QUANG CAO
	private class DownloadAdTask extends AsyncTask<String, Void, Exception> {
		@Override
		protected void onPreExecute() {
		}

		@Override
		protected Exception doInBackground(String... params) {
			String url = (String) params[0];
			try {
				downloadAdFile(url);
			} catch (Exception e) {
				e.printStackTrace();
				return e;
			}
			return null;
		}

		@Override
		protected void onPostExecute(Exception result) {
			if (result != null) {
			} else{
				//
			}
		}
	}
	
	
	
	
	///////////////////////////////////////////////////////////////////////////
	//BO QUA KIEM TRA NEU TIME-OUT (10s)
	private CountDownTimer newCountDownTimer() {
		countDownTimer = new CountDownTimer(10000, 1000) {
			@Override
			public void onTick(long millisUntilFinished) {
			}
			@Override
			public void onFinish() {
				Log.d("CountDownTimer", "onFinish.........");
				isTimeOut = true;
				if(!isFinishCheckUpdate && isFinishRequestSong){
					Log.d("CountDownTimer", "onFinish.........gotoMainView");
					gotoMainView();
				}
			}
		};
		return countDownTimer;
	}
	
	///////////////////////////////////////////////////////////////////////////
	//KIEM TRA CAP NHAT BAI HAT
	private class CheckUpdateSong extends AsyncTask<String, Void, Exception> {
		@Override
		protected void onPreExecute() {
		}
		
		@Override
		protected Exception doInBackground(String... params) {
			String url = (String) params[0];
			try {
				downloadSongUpdateInfo(url);
			} catch (Exception e) {
				e.printStackTrace();
				return e;
			}
			return null;
		}
		
		@Override
		protected void onPostExecute(Exception result) {
			if(!isTimeOut){
				Log.d("CheckUpdateSong", "finish check.........");
				isFinishCheckUpdate = true;
				if(isFinishRequestSong && AppInfo.getInstance().isHaveUpdate){
					showDialogConfirmUpdate();
				}else if(isFinishRequestSong){
					gotoMainView();
				}
			}
		}
	}
	
	
	private void downloadSongUpdateInfo(String url) { 
		File fileDir = ExternalStorage.getAdPath();
		// File path to store .zip file before unzipping
		File file = new File(fileDir.getPath() + "/songUpdate.txt");
		//File outputDir = ExternalStorage.getAdPath();
		try {
			DownloadFile.downloadWithURLConnection(url, file, fileDir);
			readFileUpdate(file);
		} finally {
			file.delete();
		}
	}
	
	
	private static void readFileUpdate(File file) {
		InputStream fis;
		BufferedReader br;
		String line;
		try {
			fis = new FileInputStream(file);
			br = new BufferedReader(new InputStreamReader(fis, Charset.forName("UTF-8")));
			SharedPreferences sharedPreferences = AppInfo.getInstance().getAppContext().getSharedPreferences(
					Splashscreen.PREFS_PRIVATE, Context.MODE_PRIVATE);
			int logId = sharedPreferences.getInt(SharedPref.SYN_LOG_ID, 0);
			
			ArrayList<OptionItemDTO> arrayLink = new ArrayList<OptionItemDTO>();
			while ((line = br.readLine()) != null) {
				line = line.trim();
				String[] array = line.split(",");
				if(logId < Integer.parseInt(array[0])){
					OptionItemDTO item = new OptionItemDTO();
					item.strText = array[1];
					item.value = Integer.parseInt(array[0]);
					arrayLink.add(0, item);
				}
			}

			if(arrayLink.size() > 0){
				AppInfo.getInstance().isHaveUpdate = true;
				AppInfo.getInstance().setListLinkUpdate(arrayLink);
				Editor prefsPrivateEditor = sharedPreferences.edit();
				prefsPrivateEditor.putBoolean(SharedPref.SYN_HAVE_UPDATE, true);
				prefsPrivateEditor.commit();
			}else{
				AppInfo.getInstance().isHaveUpdate = false;
			}
		} catch (Exception e) {
			Log.d("readFileUpdate", "Exception : " + e.getMessage());
			e.printStackTrace();
		} finally {
			br = null;
			fis = null;
		}
	}
	
	
	private void downloadAdFile(String url) { 
		File fileDir = ExternalStorage.getAdPath();
		// File path to store .zip file before unzipping
		File file = new File(fileDir.getPath() + "/ad.txt");
		//File outputDir = ExternalStorage.getAdPath();
		
		try {
			DownloadFile.downloadWithURLConnection(url, file, fileDir);
			readFile(file);
		} finally {
			file.delete();
		}
	}
	
	private static void readFile(File file) {
		InputStream fis;
		BufferedReader br;
		String line;
		try {
			fis = new FileInputStream(file);
			br = new BufferedReader(new InputStreamReader(fis, Charset.forName("UTF-8")));
			SharedPreferences sharedPreferences = AppInfo.getInstance().getAppContext().getSharedPreferences(
					Splashscreen.PREFS_PRIVATE, Context.MODE_PRIVATE);
			Editor prefsPrivateEditor = sharedPreferences.edit();
			
			if((line = br.readLine()) != null && !"".equals(line)){
				prefsPrivateEditor.putString(SharedPref.AD_IMAGE, line.trim());
			}else{
				prefsPrivateEditor.putString(SharedPref.AD_IMAGE, "");
			}
			if((line = br.readLine()) != null && !"".equals(line)){
				line = line.trim();
				if (!line.startsWith("http://") && !line.startsWith("https://"))
					line = "http://" + line;
				prefsPrivateEditor.putString(SharedPref.AD_URL, line);
			} else {
				prefsPrivateEditor.putString(SharedPref.AD_URL, "");
			}
			
			prefsPrivateEditor.commit();

		} catch (Exception e) {
			System.out.print("Exception : " + e.getMessage());
			e.printStackTrace();
		} finally {
			br = null;
			fis = null;
		}
	}
	
	
	
	
	///////////////////////////////////////////////////////////////////////////
	//THUC HIEN DOWNLOAD UPDATE BAI HAT
	public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
	private ProgressDialog mProgressDialog;

	int fileUpdate = 1;
	Handler dialogHandler = new Handler();
	Runnable showDialogRunnable = new Runnable() {
		public void run() {
			if (AppInfo.getInstance().getLinkUpdate().size() > 1) {
				showProgressDialog("Cập nhật bài hát mới, vui lòng chờ...");
				mProgressDialog.setMessage("Cập nhật bài hát (Phần " + fileUpdate + "/"
						+ AppInfo.getInstance().getLinkUpdate().size() + ")...");
			} else {
				showProgressDialog("Cập nhật bài hát mới, vui lòng chờ...");
			}
		}
	};
	Runnable closeDialogRunnable = new Runnable() {
		public void run() {
			closeProgressDialog();
		}
	};

	class UpdateDataAsync extends AsyncTask<String, String, String> {
		@Override
		protected void onPreExecute() {
			showDialog(DIALOG_DOWNLOAD_PROGRESS);
			super.onPreExecute();
		}

		@Override
		protected String doInBackground(String... arg0) {
			try {
				int fileFize = AppInfo.getInstance().getLinkUpdate().size();
				for (int i = 0; i < fileFize; i++) {
					runOnUiThread(showDialogRunnable);

					File download = downloadAndUnzip(AppInfo.getInstance().getLinkUpdate().get(i).strText);
					FileInputStream fi = new FileInputStream(download);

					// Create a POIFSFileSystem object
					POIFSFileSystem myFileSystem = new POIFSFileSystem(fi);

					// Create a workbook using the File System
					HSSFWorkbook myWorkBook = new HSSFWorkbook(myFileSystem);

					// Doc sheet thu nhat de update bai hat
					HSSFSheet sheetSong = myWorkBook.getSheetAt(0);
					Iterator<?> rowIter = sheetSong.rowIterator();
					int totalRow = sheetSong.getPhysicalNumberOfRows();
					mProgressDialog.setMax(totalRow);
					runOnUiThread(closeDialogRunnable);

					int index = 0;
					//ArrayList<String> columns = new ArrayList<String>();
					ArrayList<String> values;
					while (rowIter.hasNext()) {
						HSSFRow myRow = (HSSFRow) rowIter.next();
						//Iterator<?> cellIter = myRow.cellIterator();
						
						values = new ArrayList<String>();
						for(int j = 0; j <= 7; j++){
							HSSFCell myCell = myRow.getCell(j);
							if(myCell != null){
								values.add(myCell.toString());
							}else{
								values.add("");
							}
						}
						
						if (index != 0 && StringUtil.checkIfNumber(values.get(0).replace(".0", ""))
								&& Integer.parseInt(values.get(0).replace(".0", "")) > 0) {
							ContentValues content = initDataRow(values);
							String[] params = { values.get(0).replace(".0", "") };
							if (SQLUtils.getInstance().isExistSong(values.get(0).replace(".0", ""))) {
								// update
								SQLUtils.getInstance().getmDB().update("SONG", content, "SONG_CODE = ?", params);
							} else {
								// insert
								SQLUtils.getInstance().getmDB().insert("SONG", null, content);
							}
						}
						index++;
						publishProgress("" + index);
					}
					updateSynLastLogId(AppInfo.getInstance().getLinkUpdate().get(i).value);
					
					
					// Doc qua sheet thu 2 de update the loai bai hat
//					HSSFSheet sheetType = myWorkBook.getSheetAt(1);
//					if (sheetType != null) {
//						rowIter = sheetType.rowIterator();
//					}
					
					
					fileUpdate++;
					download = null;
					fi = null;
				}
				AppInfo.getInstance().resetListLinkUpdate();
			} catch (Throwable e) {
				e.printStackTrace();
			}
			return null;
		}

		protected void onProgressUpdate(String... progress) {
			mProgressDialog.setProgress(Integer.parseInt(progress[0]));
		}

		@Override
		protected void onPostExecute(String unused) {
			dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
			updateSynInfo();
			gotoMainView();
		}
	}

	private File downloadAndUnzip(String url) {
		File fileUpdate;
		File zipDir = ExternalStorage.getPathSynData();
		// File path to store .zip file before unzipping
		File zipFile = new File(zipDir.getPath() + "/temp.zip");
		File outputDir = ExternalStorage.getPathSynData();

		try {
			DownloadFile.downloadWithURLConnection(url, zipFile, zipDir);
			String fileName = DownloadFile.unzipReturnName(getApplicationContext(), zipFile, outputDir);
			fileUpdate = new File(zipDir.getPath() + "/" + fileName);
		} finally {
			zipFile.delete();
		}
		return fileUpdate;
	}

	private ContentValues initDataRow(ArrayList<String> values) {
		ContentValues editedValues = new ContentValues();
		try {
			editedValues.put(SongTable.COLUMN_SONG_CODE, values.get(0).replace(".0", ""));
			editedValues.put(SongTable.COLUMN_SONG_NAME, values.get(1));
			editedValues.put(SongTable.COLUMN_MUSICAN, values.get(2));
			editedValues.put(SongTable.COLUMN_SINGER, values.get(3));
			editedValues.put(SongTable.COLUMN_VOL, values.get(4).replace(".0", ""));
			editedValues.put(SongTable.COLUMN_TYPE, values.get(5).replace(".0", ""));
			editedValues.put(SongTable.COLUMN_LYRIC_SHORT, values.get(6));
			editedValues.put(SongTable.COLUMN_LYRIC_FULL, new Encryption().encrypt(AppInfo.K_LYRIC, values.get(7)));

			String nameEngUpperCase = StringUtil.getEngStringFromUnicodeString(values.get(1)).toUpperCase();
			editedValues.put(SongTable.COLUMN_SONG_NAME_SEARCH, nameEngUpperCase);
			editedValues.put(SongTable.COLUMN_MUSICAN_SEARCH, StringUtil.getEngStringFromUnicodeString(values.get(2))
					.toUpperCase());
			editedValues.put(SongTable.COLUMN_LYRIC_SEARCH, StringUtil.getEngStringFromUnicodeString(values.get(6))
					.toUpperCase());
			editedValues.put(SongTable.COLUMN_SONG_NAME_SHORT, StringUtil.getFristCharacterOfLine(nameEngUpperCase));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return editedValues;
	}

	/**
	 * Update sau khi cap nhat bai hat
	 * @author BANGHN
	 */
	private void updateSynInfo() {
		SharedPreferences sharedPreferences = AppInfo.getInstance().getAppContext()
				.getSharedPreferences(Splashscreen.PREFS_PRIVATE, Context.MODE_PRIVATE);
		Editor prefsPrivateEditor = sharedPreferences.edit();
		prefsPrivateEditor.putString(SharedPref.SYN_LAST_DATE, DateUtil.now(DateUtil.TIME_UPDATE));
		boolean isHavaUpdate = false;
		if (AppInfo.getInstance().getLinkUpdate().size() > 0)
			isHavaUpdate = true;
		prefsPrivateEditor.putBoolean(SharedPref.SYN_HAVE_UPDATE, isHavaUpdate);
		prefsPrivateEditor.commit();
	}
	
	/**
	 * Update sau khi khoi tao du lieu
	 * @author BANGHN
	 */
	private void updateSynInfoAfterInit() {
		SharedPreferences sharedPreferences = AppInfo.getInstance().getAppContext()
				.getSharedPreferences(Splashscreen.PREFS_PRIVATE, Context.MODE_PRIVATE);
		Editor prefsPrivateEditor = sharedPreferences.edit();
		prefsPrivateEditor.putInt(SharedPref.SYN_LOG_ID, 17);
		prefsPrivateEditor.commit();
	}

	private void updateSynLastLogId(int logId) {
		SharedPreferences sharedPreferences = AppInfo.getInstance().getAppContext()
				.getSharedPreferences(Splashscreen.PREFS_PRIVATE, Context.MODE_PRIVATE);
		int lastLogId = sharedPreferences.getInt(SharedPref.SYN_LOG_ID, 0);
		if (logId > lastLogId) {
			Editor prefsPrivateEditor = sharedPreferences.edit();
			prefsPrivateEditor.putInt(SharedPref.SYN_LOG_ID, logId);
			prefsPrivateEditor.commit();
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DIALOG_DOWNLOAD_PROGRESS:
			mProgressDialog = new ProgressDialog(this);
			mProgressDialog.setMax(0);
			mProgressDialog.setMessage("Cập nhật bài hát..");
			mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			mProgressDialog.setCancelable(false);
			mProgressDialog.show();
			return mProgressDialog;
		default:
			return null;
		}
	}
}
